﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Graphics;

namespace DARE
{
    /// <summary>
    /// Class use for content data to be serialized and recreate RasterizerState
    /// </summary>
    public class CRasterizationContent
    {
        #region Fields

        private bool m_dataChanged;
        private RasterizerState m_state;
        private CullMode m_cullMode;
        private float m_depthBias;
        private FillMode m_fillMode;
        private bool m_multiSampleAntiAlias;
        private bool m_scissorTestEnable;

        #endregion

        #region Property

        /// <summary>
        /// RasterizerState, Not serialise
        /// </summary>
        public RasterizerState State
        {
            get
            { 
                return this;
            }
        }

        /// <Summary>
        ///     Specifies the conditions for culling or removing triangles. The default value
        ///     is CullMode.CounterClockwise.
        /// </summary>
        public CullMode CullMode
        {
            get { return this.m_cullMode; }
            set
            {
                if (this.m_cullMode != value)
                {
                    this.m_cullMode = value;
                    m_dataChanged = true;
                }
            }
        }

        /// <summary>
        /// Sets or retrieves the depth bias for polygons, which is the amount of bias
        /// to apply to the depth of a primitive to alleviate depth testing problems
        /// for primitives of similar depth. The default value is 0.
        /// </summary>
        public float DepthBias
        {
            get { return this.m_depthBias; }
            set
            {
                if (this.m_depthBias != value)
                {
                    this.m_depthBias = value;
                    m_dataChanged = true;
                }
            }
        }

        /// <summary>
        /// The fill mode, which defines how a triangle is filled during rendering. The
        /// default is FillMode.Solid.
        /// </summary>
        public FillMode FillMode
        {
            get { return this.m_fillMode; }
            set
            {
                if (this.m_fillMode != value)
                {
                    this.m_fillMode = value;
                    this.m_dataChanged = true;
                }
            }
        }

        /// <summary>
        /// Enables or disables multisample antialiasing. The default is true.
        /// </summary>
        public bool MultiSampleAntiAlias
        {
            get { return this.m_multiSampleAntiAlias; }
            set
            {
                if (this.m_multiSampleAntiAlias != value)
                {
                    this.m_multiSampleAntiAlias = value;
                    m_dataChanged = true;
                }
            }
        }

        /// <summary>
        /// Enables or disables scissor testing. The default is false.
        /// </summary>
        public bool ScissorTestEnable
        {
            get { return this.m_scissorTestEnable; }
            set
            {
                if (this.m_scissorTestEnable != value)
                {
                    this.m_scissorTestEnable = value;
                    this.m_dataChanged = true;
                }
            }
        }

        /// <summary>
        /// Gets or sets a bias value that takes into account the slope of a polygon.
        /// This bias value is applied to coplanar primitives to reduce aliasing and
        /// other rendering artifacts caused by z-fighting. The default is 0.
        /// </summary>
        public float SlopeScaleDepthBias { get; set; }

        public bool DataChanged
        {
            get
            {
                return this.m_dataChanged;
            }
        }

        #endregion

        #region CTOR

        public CRasterizationContent(RasterizerState state)
        {
            this.CullMode = state.CullMode;
            this.DepthBias = state.DepthBias;
            this.FillMode = state.FillMode;
            this.MultiSampleAntiAlias = state.MultiSampleAntiAlias;
            this.ScissorTestEnable = state.ScissorTestEnable;
            this.SlopeScaleDepthBias = state.SlopeScaleDepthBias;
        }

        public CRasterizationContent()
        {

        }

        #endregion

        #region Method

        public static implicit operator RasterizerState(CRasterizationContent ct)
        {
            if (ct == null)
                return null;
            if (ct.m_state == null || ct.m_dataChanged)
                ct.m_state = new RasterizerState()
                {
                    CullMode = ct.CullMode,
                    DepthBias = ct.DepthBias,
                    FillMode = ct.FillMode,
                    MultiSampleAntiAlias = ct.MultiSampleAntiAlias,
                    ScissorTestEnable = ct.ScissorTestEnable,
                    SlopeScaleDepthBias = ct.SlopeScaleDepthBias
                };
            return ct.m_state;
        }

        #endregion
    }
}
